package com.example.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.Result;
import com.example.entity.Admin;
import com.example.service.AdminService;
import com.example.util.TokenUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 全局拦截器
 */
@Slf4j
@Component
public class GlobalInterceptor implements HandlerInterceptor {

    private final AdminService adminService;
    private final ObjectMapper objectMapper;

    public GlobalInterceptor(AdminService adminService, ObjectMapper objectMapper) {
        this.adminService = adminService;
        this.objectMapper = objectMapper;
    }

    // 需要放行的路径
    private static final List<String> EXCLUDE_PATHS = Arrays.asList(
        "/admin/login",           // 管理员登录
        "/user/login",            // 用户登录
        "/user/register",         // 用户注册
        "/swagger-ui.html",       // Swagger UI
        "/swagger-resources",     // Swagger资源
        "/v2/api-docs",           // Swagger API文档
        "/webjars",               // WebJars资源
        "/error"                  // 错误页面
    );

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求路径
        String requestURI = request.getRequestURI();
        log.info("拦截到请求: {}", requestURI);

        // 1. 放行OPTIONS请求
        if ("OPTIONS".equals(request.getMethod())) {
            log.info("放行OPTIONS请求");
            return true;
        }

        // 2. 放行静态资源和不需要认证的接口
        for (String path : EXCLUDE_PATHS) {
            if (requestURI.contains(path)) {
                log.info("放行路径: {}", path);
                return true;
            }
        }

        // 3. 放行静态资源
        if (requestURI.startsWith("/static/") ||
            requestURI.endsWith(".html") ||
            requestURI.endsWith(".js") ||
            requestURI.endsWith(".css") ||
            requestURI.endsWith(".jpg") ||
            requestURI.endsWith(".png")) {
            log.info("放行静态资源: {}", requestURI);
            return true;
        }

        // 4. 获取请求头中的token
        String token = request.getHeader("Authorization");
        if (!StringUtils.hasText(token)) {
            log.warn("未找到token");
            handleError(response, "未登录");
            return false;
        }

        // 5. 去掉Bearer前缀
        if (token.startsWith("Bearer ")) {
            token = token.substring(7);
        }

        // 6. 查询管理员
        Admin admin = adminService.getOne(new LambdaQueryWrapper<Admin>()
            .eq(Admin::getToken, token)
            .eq(Admin::getDeleted, 0));

        if (admin == null) {
            log.warn("token无效: {}", token);
            handleError(response, "token无效");
            return false;
        }

        // 7. 校验token是否过期
        if (TokenUtil.isTokenExpired(admin.getTokenExpireTime().format(TokenUtil.formatter))) {
            log.warn("token已过期: {}", token);
            handleError(response, "token已过期");
            return false;
        }

        // 8. 校验管理员状态
        if (admin.getStatus() != 1) {
            log.warn("管理员已被禁用: {}", admin.getId());
            handleError(response, "管理员已被禁用");
            return false;
        }

        // 9. 将管理员信息存入request属性中
        request.setAttribute("currentAdmin", admin);
        log.info("请求验证通过: {}", requestURI);

        return true;
    }

    private void handleError(HttpServletResponse response, String message) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().write(objectMapper.writeValueAsString(Result.error(message)));
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) {
        // 请求处理后的逻辑
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 请求完成后的逻辑
    }
}